<?php
/**
 *
 * @createTime: 2016-06-07 21:01
 * @description:  常用的数组处理工具
 * @link      https://github.com/helei112g/payment/tree/paymentv2
 * @link      https://helei112g.github.io/
 */

namespace Payment\Utils;

class ArrayUtil
{

    /**
     * 移除空值的key
     * @param $para
     * @return array
     * @author helei
     */
    public static function paraFilter($para)
    {
        $paraFilter = [];
        foreach ($para as $key => $val) {
            if ($val === '' || $val === null) {
                continue;
            } else {
                if (!is_array($para[$key])) {
                    $para[$key] = is_bool($para[$key]) ? $para[$key] : trim($para[$key]);
                }

                $paraFilter[$key] = $para[$key];
            }
        }

        return $paraFilter;
    }

    /**
     * 删除一位数组中，指定的key与对应的值
     * @param array $inputs 要操作的数组
     * @param array|string $keys 需要删除的key的数组，或者用（,）链接的字符串
     * @return array
     */
    public static function removeKeys(array $inputs, $keys)
    {
        if (!is_array($keys)) {// 如果不是数组，需要进行转换
            $keys = explode(',', $keys);
        }

        if (empty($keys) || !is_array($keys)) {
            return $inputs;
        }

        $flag = true;
        foreach ($keys as $key) {
            if (array_key_exists($key, $inputs)) {
                if (is_int($key)) {
                    $flag = false;
                }
                unset($inputs[$key]);
            }
        }

        if (!$flag) {
            $inputs = array_values($inputs);
        }
        return $inputs;
    }

    /**
     * 对输入的数组进行字典排序
     * @param array $param 需要排序的数组
     * @return array
     *
     */
    public static function arraySort(array $param)
    {
        ksort($param);
        reset($param);

        return $param;
    }

    /**
     * 把数组所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串
     * @param array $para 需要拼接的数组
     * @param bool $urlDecode
     * @return string
     * @throws \Exception
     */
    public static function createLinkstring($para, bool $urlDecode = true)
    {
        if (!is_array($para)) {
            throw new \Exception('必须传入数组参数');
        }

        reset($para);
        $arg = '';
        foreach ($para as $key => $val) {
            if (is_array($val)) {
                continue;
            }

            $arg .= $key . '=' . (true === $urlDecode ? urldecode($val) : $val) . '&';
        }
        //去掉最后一个&字符
        $arg && $arg = substr($arg, 0, -1);

        //如果存在转义字符，那么去掉转义
        if (get_magic_quotes_gpc()) {
            $arg = stripslashes($arg);
        }

        return $arg;
    }


    /**
     * 将参数数组签名
     */
    public static function SignArray(array $array, $appkey)
    {
        $array['key'] = $appkey;// 将key放到数组中一起进行排序和组装
        ksort($array);
        $blankStr = self::ToUrlParams($array);
        $sign = md5($blankStr);
        return $sign;
    }

    public static function ToUrlParams(array $array)
    {
        $buff = "";
        foreach ($array as $k => $v) {
            if ($v != "" && !is_array($v)) {
                $buff .= $k . "=" . $v . "&";
            }
        }

        $buff = trim($buff, "&");
        return $buff;
    }

    /**
     * 校验签名
     * @param array
     * @param $appkey
     * @return bool
     */
    public static function ValidSign(array $array, $appkey)
    {
        $sign = $array['sign'];
        unset($array['sign']);
        $array['key'] = $appkey;
        $mySign = self::SignArray($array, $appkey);
        return strtolower($sign) == strtolower($mySign);
    }

    public static function SignRSA($param, $keyPath)
    {
        ksort($param);
        $str = '';
        foreach ($param as $key => $value) {
            if (!empty($str)) {
                $str .= '&' . $key . '=' . $value;
            } else {
                $str .= $key . '=' . $value;
            }
        }
        $private_key = file_get_contents($keyPath);
        if (empty($private_key)) {
            echo "Private Key error!";
            exit;
        }

        $pkeyid = openssl_get_privatekey($private_key);
        if (empty($pkeyid)) {
            echo "private key resource identifier False!";
            exit;
        }

        $str = urlencode($str);
        $verify = openssl_sign($str, $signature, $pkeyid, OPENSSL_ALGO_SHA256);
        openssl_free_key($pkeyid);
        return base64_encode($signature);
    }

    /**
     * 米付签名校验
     *
     * @param $param
     * @param $keyPath
     * @return bool|int
     */
    public static function SignVerify($param, $keyPath)
    {
        $signature = base64_decode($param['sign']);
        unset($param['sign']);

        ksort($param);
        $str = '';
        foreach ($param as $key => $value) {
            if (!empty($str)) {
                $str .= '&' . $key . '=' . $value;
            } else {
                $str .= $key . '=' . $value;
            }
        }

        $public_key = file_get_contents($keyPath);
        if (empty($public_key)) {
            echo "public Key error!";
            exit;
        }

        $pkeyid = openssl_get_publickey($public_key);
        if (empty($pkeyid)) {
            echo "public key resource identifier False!";
            exit;
        }

        $str = urlencode($str);
        $verify = openssl_verify($str, $signature, $pkeyid, OPENSSL_ALGO_SHA256);

        return $verify;
    }
}
